package server.comunicacion;


//import cliente.comunicacion.ICliente;
import cliente.comunicacion.ICliente;
import herramientas.Agente_Properties;
import java.io.FileNotFoundException;
import java.io.IOException;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.sql.SQLException;
import java.util.Date;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.comunicacion.ServidorA;

import server.dominio.Beneficiario;
import server.dominio.Cita;
import server.dominio.ISesion;
import server.dominio.Medico;

import server.excepciones.BeneficiarioInexistenteException;
import server.excepciones.BeneficiarioNoExistenteException;
import server.excepciones.BeneficiarioYaExistenteException;
import server.excepciones.CitaNoValidaException;
import server.excepciones.FechaNoValidaException;
import server.excepciones.MedicoInexistenteException;
import server.excepciones.MedicoNoExistenteException;
import server.excepciones.MedicoYaExistenteException;
import server.excepciones.UsuarioIncorrectoException;
import server.excepciones.VolanteNoValidoException;
import server.negocio.Controlador_G_Citas;

import server.negocio.Controlador_G_Usuarios;
import server.negocio.Controlador_Horario;
import server.negocio.Controlador_Login;
import server.negocio.Controlador_MensajeAux;
import server.negocio.Controlador_Servidor;

import server.presentacion.JF_Servidor;
import server.presentacion.iJF_Servidor;



public class ServidorA extends UnicastRemoteObject implements IServidorA {

	/**
	 * 
	 */
    private static final long serialVersionUID = 1L;
//    private Hashtable<ID_iSESION, iCliente> sesiones;

    private Controlador_Servidor c_servidor;
    private Controlador_Login c_login;
    private Controlador_G_Usuarios c_g_usuarios;
    private Controlador_MensajeAux c_mensajeaux;
    private Controlador_Horario c_horario;
    private Controlador_G_Citas c_g_citas;
    private iJF_Servidor ventanaservidor;
    private String puerto= "2997";
    public ServidorA() throws RemoteException {
            super();
            LocateRegistry.createRegistry(2994);

            ventanaservidor= new JF_Servidor(this);
            
            //Inicialización del controlador
            c_servidor= new Controlador_Servidor(this, ventanaservidor);
            c_login= new Controlador_Login(c_servidor);
            c_g_usuarios= new Controlador_G_Usuarios(c_servidor);
            c_horario= new Controlador_Horario(c_servidor);
                        c_g_citas= new Controlador_G_Citas(c_servidor, c_g_usuarios, c_horario);
            c_mensajeaux= new Controlador_MensajeAux(c_servidor, c_g_usuarios, c_horario, c_g_citas);
        try {
            Agente_Properties pop = Agente_Properties.getAgenteProperties();
            puerto= pop.getProperty("servidorA.puerto");
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ServidorA.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ServidorA.class.getName()).log(Level.SEVERE, null, ex);
        }
	}

    public static void main(String [] args){
        try {
            ServidorA server = new ServidorA();
        } catch (RemoteException ex) {
            Logger.getLogger(ServidorA.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public void conectar() throws MalformedURLException, RemoteException {
        try {
            Naming.bind("rmi://localhost:"+puerto+"/ServidorA", this);
            c_servidor.log("Naming_bind: rmi://localhost:"+puerto+"/ServidorA OK");
        }
        catch (AlreadyBoundException ex) {
            Naming.rebind("rmi://localhost:2994/ServidorA", this);
            c_servidor.log("Naming_rebind: rmi://localhost:"+puerto+"/ServidorA OK");
        }

    }

    public void desconectar() throws RemoteException, MalformedURLException, NotBoundException {
        Naming.unbind("rmi://localhost:"+puerto+"/ServidorA");
        c_servidor.log("Naming_unbind: rmi://localhost:"+puerto+"/ServidorA OK");
    }


	
    @Override
    public ISesion identificar(String login, String password) throws RemoteException, UsuarioIncorrectoException, SQLException {
            //return sesion
           return c_login.login(login, password);
    }

    public void registrar(long idSesion, ICliente cliente) throws RemoteException, Exception {
        c_servidor.registrar(idSesion, cliente);
    }

    @Override
    public Beneficiario getBeneficiario(long idSesion, String dni)
                    throws RemoteException, BeneficiarioInexistenteException,
                    SQLException, Exception {
        // TODO Auto-generated method stub
        return c_g_usuarios.obtenerBeneficiario(idSesion, dni);
    }

    @Override
    public Beneficiario getBeneficiarioPorNSS(long idSesion, String nss)
                    throws RemoteException, BeneficiarioInexistenteException,
                    SQLException, Exception {
            // TODO Auto-generated method stub
            return c_g_usuarios.obtenerBeneficiarionss(idSesion, nss);
    }
    @Override
    public Medico getMedico(long idSesion, String dni) throws RemoteException,
                    MedicoInexistenteException, SQLException, Exception {
            // TODO Auto-generated method stub
            return c_g_usuarios.obtenerMedico(idSesion, dni);
    }






    @Override
    public void crear(long idSesion, Beneficiario beneficiario)
                    throws RemoteException, BeneficiarioYaExistenteException,
                    SQLException, Exception {

        c_g_usuarios.crearbeneficiario(idSesion, beneficiario);
    }
    @Override
    public void crear(long idSesion, Medico medico) throws RemoteException,
                    MedicoYaExistenteException, SQLException, Exception {
            // TODO Auto-generated method stub
           c_g_usuarios.crearmedico(idSesion, medico);
    }


    @Override
    public void modificar(long idSesion, Medico medico) throws RemoteException,
                    MedicoNoExistenteException, SQLException, Exception {
            // TODO Auto-generated method stub
        c_g_usuarios.modificarMedico(idSesion, medico);
    }
    @Override
    public void modificar(long idSesion, Beneficiario beneficiario)
                    throws RemoteException, BeneficiarioNoExistenteException,
                    SQLException, Exception {
            // TODO Auto-generated method stub
        c_g_usuarios.modificarBeneficiario(idSesion, beneficiario);

    }
    public void modificarCalendario(long idSesion, Medico medico, Vector<Date> dias, Date horaDesde, Date horaHasta, Medico sustituto) throws RemoteException, Exception{
        c_horario.insertarDatos(idSesion, medico, dias, horaDesde, horaHasta);
    }



    public void eliminar(long idSesion, Beneficiario beneficiario) throws RemoteException, BeneficiarioNoExistenteException, SQLException, Exception {
        c_g_usuarios.eliminarbeneficiario(idSesion, beneficiario);
    }
    @Override
    public void eliminar(long idSesion, Medico medico) throws RemoteException,
                    MedicoNoExistenteException, SQLException, Exception {
           c_g_usuarios.eliminarmedico(idSesion, medico);

    }

    public void mensajeAuxiliar(long idSesion, long codigoDeMensaje, Object informacion) throws RemoteException, SQLException, Exception {
        c_mensajeaux.analizarmensajeAuxiliar(idSesion, codigoDeMensaje, informacion);
    }

    public Cita pedirCita(long idSesion, Beneficiario beneficiario, String idMedico, Date fechayHora, long duracion) throws RemoteException, BeneficiarioInexistenteException, MedicoInexistenteException, FechaNoValidaException, SQLException, Exception {
       return c_g_citas.pedirCita(idSesion, beneficiario, idMedico, fechayHora, duracion);
    }

    public Cita pedirCita(long idSesion, Beneficiario beneficiario, long idVolante, Date fechayHora, long duracion) throws RemoteException, BeneficiarioInexistenteException, MedicoInexistenteException, FechaNoValidaException, VolanteNoValidoException, SQLException, Exception {
        return c_g_citas.pedirCita(idSesion, beneficiario, idVolante, fechayHora, duracion);
     }

    public Vector<Cita> getCitas(long idSesion, String dni) throws RemoteException, BeneficiarioInexistenteException, SQLException, Exception {
        return c_g_citas.getCitas(idSesion, dni);
    }

    public void anularCita(long idSesion, Cita cita) throws RemoteException, CitaNoValidaException, SQLException, Exception {
        c_g_citas.anularCita(idSesion, cita);
    }

    public void liberar(long idSesion) throws RemoteException, Exception {
        c_servidor.eliminarsesion(idSesion);
    }

}

